package com.cloudspace.yunloan.cropimage;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;

import com.cloudspace.yunloan.R;
import com.cloudspace.yunloan.activity.YunloanActivity;
import com.cloudspace.yunloan.module.ActionItem;
import com.cloudspace.yunloan.utils.ConvertUtils;

import java.io.Closeable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class CropImageActivity extends YunloanActivity {

    private CropImageLayout mImageView;
    private Uri mSaveUri;
    private int mMaxWidth;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.crop_image_layout);
        mImageView = (CropImageLayout) findViewById(R.id.clip);
        setupFromIntent();

        ActionItem leftItem = new ActionItem(null, R.drawable.backbtn_white, new OnClickListener() {
            @Override
            public void onClick(View view) {
                setResult(RESULT_CANCELED);
                finish();
            }
        });
        ActionItem rightItem = new ActionItem("使用", new OnClickListener() {
            @Override
            public void onClick(View view) {
                saveOutput();

                Intent data = new Intent();
                data.putExtra(RESULT_OUTPUT_PATH, mSaveUri);
                setResult(RESULT_OK, data);
                finish();
            }
        });
        getTitleBar().getRightView().setTextSize(ConvertUtils.dp2px(9));
        getTitleBar().setSimpleMode("", leftItem, rightItem);
        getTitleBar().setTitleBarBackground(android.R.color.black);
        getTitleBar().setTitleColor(getResources().getColor(R.color.base_txt_white1));
    }

    private void setupFromIntent() {
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();

        if (extras != null) {
            mMaxWidth = extras.getInt(EXTRA_MAX_WIDTH);
            mSaveUri = extras.getParcelable(MediaStore.EXTRA_OUTPUT);
        }

        Uri data = getIntent().getData();
        if (data == null) {
            finish();
        }
        InputStream is = null;
        try {
            int sampleSize = calculateBitmapSampleSize(data);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = sampleSize;
            is = getContentResolver().openInputStream(data);
            Bitmap b = BitmapFactory.decodeStream(is, null, options);
            displayRotateBitmap(b, getExifRotation(data));
        } catch (Exception e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        } finally {
            closeSilently(is);
        }
    }

    private void displayRotateBitmap(Bitmap bm, int degree) {
        if (bm != null && !bm.isRecycled()) {
            if (degree > 0) {
                Matrix matrix = new Matrix();
                matrix.postRotate(degree);
                try {
                    Bitmap rotateBmp = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
                    mImageView.setImageBitmap(rotateBmp);
                    recycleBitmap(bm);
                } catch (OutOfMemoryError e) {
                    mImageView.setImageBitmap(bm);
                }
            } else {
                mImageView.setImageBitmap(bm);
            }
        }
    }

    private static int getExifRotation(Uri imageFileUri) {
        if (imageFileUri == null) {
            return 0;
        }
        try {
            ExifInterface exif = new ExifInterface(imageFileUri.getPath());
            switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    return 90;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    return 180;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    return 270;
                default:
                    return ExifInterface.ORIENTATION_UNDEFINED;
            }
        } catch (IOException e) {
            return 0;
        }
    }

    private int calculateBitmapSampleSize(Uri bitmapUri) throws IOException {
        InputStream is = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        try {
            is = getContentResolver().openInputStream(bitmapUri);
            BitmapFactory.decodeStream(is, null, options); // Just get image size
        } catch (IOException e) {
        } catch (OutOfMemoryError error) {
        } finally {
            closeSilently(is);
        }
        int maxSize = getMaxImageSize();
        int sampleSize = 1;
        while (options.outHeight / sampleSize > maxSize || options.outWidth / sampleSize > maxSize) {
            sampleSize = sampleSize << 1;
        }
        return sampleSize;
    }

    private int getMaxImageSize() {
        int textureLimit = getScreenHeight(this);
        if (textureLimit == 0) {
            return CropImageLayout.MAX_WIDTH;
        } else {
            return Math.min(textureLimit, CropImageLayout.MAX_WIDTH);
        }
    }

    private static int getScreenHeight(Activity context) {
        DisplayMetrics dm = new DisplayMetrics();
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }

    private static int getScreenWidth(Activity context) {
        DisplayMetrics dm = new DisplayMetrics();
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }

    private void saveOutput() {
        if (mSaveUri != null) {
            OutputStream outputStream = null;
            Bitmap b = null;
            try {
                outputStream = new FileOutputStream(mSaveUri.getPath());
                b = mImageView.clip();
                if (outputStream != null && b != null) {
                    if (mMaxWidth > 0 && b.getWidth() > mMaxWidth) {
                        b = Bitmap.createScaledBitmap(b, mMaxWidth, mMaxWidth, true);
                    }
                    b.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
                }
            } catch (IOException e) {
            } catch (OutOfMemoryError error) {
            } finally {
                closeSilently(outputStream);
            }
        }
    }

    private static void closeSilently(Closeable c) {
        if (c == null) return;
        try {
            c.close();
        } catch (Throwable t) {
            // Do nothing
        }
    }

    private static void recycleBitmap(Bitmap bmp) {
        if (bmp != null && !bmp.isRecycled()) {
            bmp.recycle();
        }
    }

    private static final String EXTRA_MAX_WIDTH = "max_width";
    public static final String RESULT_OUTPUT_PATH = "result_output_path";

    public static void show(Activity activity, int requestCode, Uri sourceImgUri, Uri outImgUri) {
        Intent intent = new Intent(activity, CropImageActivity.class);
        intent.setData(sourceImgUri);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outImgUri);
        intent.putExtra(EXTRA_MAX_WIDTH, getScreenWidth(activity));
        activity.startActivityForResult(intent, requestCode);
    }

}